package com.xjc.infra.encrypt;

import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import com.xjc.infra.exception.IFSException;
import com.xjc.infra.util.SystemGlobals;

/**
 * 加密工具
 * @author liangcz
 * @Date   2017年12月1日 下午8:13:36
 * @version 1.0
 */
public class SecurityUtil {
	
	/**
	 * DESede算法生成一个168位的对称密钥
	 * @author liangcz
	 * @date   2017年12月1日 下午8:11:30
	 * @return Key
	 */
	public static Key generateSymmetricKey() throws NoSuchAlgorithmException {
		try {
			String algorithm = "DESede";
			KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
			keyGenerator.init(168);
			Key key = keyGenerator.generateKey();
			keyGenerator = null;
			return key;
		} catch (IFSException e) {
			throw e;
		} catch (Exception e) {
			throw new IFSException(e, "SecurityUtil.generateSymmetricKey.99", "生成对称密钥失败");
		}
	}
	/**
	 * 使用对称密钥加密
	 * @author liangcz
	 * @date   2017年12月1日 下午8:16:50
	 * @return byte[]
	 */
	public static byte[] encryptSymmetry(String plainText, Key key) {
		try {
			Cipher tCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
			tCipher.init(1, key);
			byte[] tCipherText = tCipher.doFinal(plainText.getBytes(SystemGlobals.getProperty("sys.encoding","UTF-8")));
			tCipher = null;
			return tCipherText;
		} catch (IFSException e) {
			throw e;
		} catch (Exception e) {
			throw new IFSException(e, "SecurityUtil.encryptSymmetry.99", "使用对称密钥加密失败");
		}
	}

	public static byte[] encryptSymmetricKey(Key key, PublicKey receiverPubKey){
		try {
			Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
			cipher.init(1, receiverPubKey);

			byte[] keyBytes = key.getEncoded();

			byte[] cipherText = cipher.doFinal(keyBytes);
			cipher = null;

			return cipherText;
		} catch (IFSException e) {
			throw e;
		} catch (Exception e) {
			throw new IFSException(e, "SecurityUtil.encryptSymmetricKey.99", "对称密钥key加密失败");
		}
	}
	/**
	 * 对称密钥解密
	 * @author liangcz
	 * @date   2017年12月1日 下午9:38:19
	 * @return Key
	 */
	public static Key decryptSymmetricKey(byte[] encryptedKey,PrivateKey receiverPriKey) {
		try {
			String algorithm = "DESede";
			Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // RSA/ECB/PKCS1Padding
			cipher.init(2, receiverPriKey);
			byte[] decryptedKeyBytes = cipher.doFinal(encryptedKey);
			SecretKey key = new SecretKeySpec(decryptedKeyBytes, algorithm);
			return key;
		} catch (IFSException e) {
			throw e;
		} catch (Exception e) {
			throw new IFSException(e, "SecurityUtil.decryptSymmetricKey.99", "对称密钥解密失败");
		}
	}
	/**
	 * 解密
	 * @author liangcz
	 * @date   2017年12月1日 下午9:43:20
	 * @return String
	 */
	public static String decryptSymmetry(byte[] cipherText, Key key) {
		try {
			Cipher tCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
			tCipher.init(2, key);
			byte[] tPlainText = tCipher.doFinal(cipherText);
			String encoding = SystemGlobals.getProperty("sys.encoding");
			return new String(tPlainText,encoding);
		} catch (IFSException e) {
			throw e;
		} catch (Exception e) {
			throw new IFSException(e, "SecurityUtil.decryptSymmetry.99", "解密失败");
		}
		
	}
}
